package server;

import java.util.ArrayList;

/**
 * class Account is an entity with specific data about the account
 * 
 * @author Rasmus Stjerne, Joachim Lindholm, Daniel Gramstrup, Pamela Pedersen
 * 
 */
public class Account {

	private String accountPassword; // Password string
	private double balance; // Current account balance as a double
	private String name; // The full name of the accountant
	public static final double CCKMFACTOR = 2.0; // Specified by the sum of the
													// digits 1991 = 2
	private ArrayList<Transaction> transactions; // ArrayList containing all
													// transactions ever related
													// to the specific account
	private boolean userAuthenticated = false; // Boolean to confirm wether the
												// user is allready logged in

	/**
	 * Account constructor initializes attributes
	 * 
	 * @param password
	 *            - containing the account password
	 * @param name
	 *            - the account name
	 * @param balance
	 *            - the balance of the account
	 */
	public Account(String password, String name, double balance) {
		this.accountPassword = password;
		this.name = name;
		this.balance = balance;
		this.transactions = new ArrayList<Transaction>();
	}

	/**
	 * Add a new transaciton to the transaction list
	 * 
	 * @param transaction
	 *            - A transaction consist of a id, sender, reciever, amount and
	 *            current status eg. pending
	 */
	public void addTransaction(Transaction transaction) {
		transactions.add(transaction);
	}

	/**
	 * Accept a transaction based on a specific id
	 * 
	 * @param id
	 *            - specific transaction id as argument
	 */
	public void accept(int id) {
		for (Transaction t : transactions) {
			if (t.getID() == id) {
				transfer(t.getAmount());
				t.accept();
			}
		}
	}

	/**
	 * Decline a transaction based on a specific id
	 * 
	 * @param id
	 *            - specific transaction id as argument
	 */
	public void decline(int id) {
		for (Transaction t : transactions) {
			if (t.getID() == id) {
				t.decline();
			}
		}
	}

	/**
	 * Accumulate all the transactions with pending status
	 * 
	 * @return the pending balance
	 */
	public double getPendingBalance() {
		double balance = 0;
		for (Transaction t : transactions) {
			// using custom enum to check status
			if (t.getStatus() == Transaction.Status.pending) {
				balance += t.getAmount();
			}
		}
		return balance;
	}

	/**
	 * Subtract the pending balance from the current balance of the account
	 * 
	 * @return the total balance
	 */
	public double getTotalBalance() {
		return this.balance + getPendingBalance();
	}

	/**
	 * Get the specific transaction based on the supplied transaction id
	 * 
	 * @param transactionId
	 * @return the transaction object corresponding to the transaction id
	 */
	public Transaction getTransaction(int transactionId) {
		Transaction tmp = null;
		for (Transaction t : transactions) {
			if (t.getID() == transactionId)
				tmp = t;
		}
		return tmp;
	}

	/**
	 * Used to compile a list of all pending transaction
	 * 
	 * @return list of pending transactions
	 */
	public ArrayList<Transaction> getPendingTransactions(String recipient) {
		ArrayList<Transaction> pendingTransactions = new ArrayList<Transaction>();
		for (Transaction t : transactions) {
			// using custom enum to check status
			if (t.getStatus() == Transaction.Status.pending
					&& t.getRecipient().equals(recipient)) {
				pendingTransactions.add(t);
			}
		}
		return pendingTransactions;
	}

	/**
	 * Control if the supplied password is correct
	 * 
	 * @param password
	 * @return true if the password corresponds to the account otherwise returns
	 *         false
	 */
	public boolean validatePassword(String password) {
		if (password.equals(this.accountPassword)
				&& this.userAuthenticated == false) {
			this.userAuthenticated = true;
			return true;
		} else
			return false;
	}

	/**
	 * Check whether the user is already logged in
	 * 
	 * @return true if the user is already logged in
	 */
	public boolean isUserAuthenticated() {
		return this.userAuthenticated;
	}

	/**
	 * Used when the user logs off
	 */
	public void logout() {
		this.userAuthenticated = false;
	}

	/**
	 * Get method to the current balance
	 * 
	 * @return the current balance
	 */
	public double getBalance() {
		return balance;
	}

	/**
	 * Insert CC to the account. The CCKMFACTOR is multiplied on the supplied
	 * amount
	 * 
	 * @param amount
	 *            contains how many KM the user wants to insert
	 */
	public void insert(double amount) {
		balance += amount * CCKMFACTOR; // add to total balance
	}

	public String getName() {
		return this.name;
	}

	/**
	 * Spend CC from the account. The CCUSEFACTOR is computed directly from
	 * yahoo thru the @Parser class
	 * 
	 * @param amount
	 */
	public void spend(double amount) {
		balance -= amount * Parser.computeCCUSEFACTOR(); // subtract from the
															// balance
	}

	/**
	 * Used to transfer CC between to different Accounts
	 * 
	 * @param amount
	 *            specified by the user. Limit based on the balance
	 */
	public void transfer(double amount) {
		balance += amount;
	}
}
